<script setup lang="ts">
import { onBeforeUnmount, ref } from 'vue';
import { useAuthStore } from '@/store/modules/auth';

const videoElement = ref<HTMLVideoElement | null>(null);
const error = ref<string | null>(null);
const cameraActive = ref<boolean>(false);
const videoFilter = ref<string>('none');
const websocket = ref<WebSocket | null>(null);
let frameInterval: number | NodeJS.Timeout | null = null;

const authStore = useAuthStore();

// 关闭WebSocket连接
const closeWebSocket = () => {
  if (websocket.value) {
    websocket.value.close();
  }
};

// 定义WebSocket连接
const setupWebSocket = () => {
  websocket.value = new WebSocket('ws://127.0.0.1:8000/ws/recognize');
  websocket.value.onopen = () => {
    console.log('WebSocket连接已建立');
  };
  websocket.value.onclose = () => {
    console.log('WebSocket连接已关闭');
  };
  // 接收后端发来的消息
  websocket.value.onmessage = async event => {
    const data = JSON.parse(event.data);
    if (data.code === 200) {
      closeWebSocket();
      // 登陆成功
      await authStore.loginByUserId(data.data);
    }
  };
};

// 捕获当前帧并发送
const captureFrame = () => {
  if (!videoElement.value || !websocket.value || websocket.value.readyState !== WebSocket.OPEN) return;

  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');
  if (ctx && videoElement.value.videoWidth && videoElement.value.videoHeight) {
    // 设置canvas的尺寸为视频的尺寸
    canvas.width = videoElement.value.videoWidth;
    canvas.height = videoElement.value.videoHeight;

    // 将视频帧绘制到canvas上
    ctx.drawImage(videoElement.value, 0, 0, canvas.width, canvas.height);

    // 将canvas内容转换为图片数据（Base64）
    const imageData = canvas.toDataURL('image/jpeg'); // 图片格式为JPEG，质量为0.8

    // 将Base64图像数据发送到WebSocket后端
    websocket.value.send(imageData.split(',')[1]);
    console.log('已发送图像数据');
  }
};

const stopSendingFrames = () => {
  if (frameInterval !== null) {
    clearInterval(frameInterval);
    frameInterval = null;
  }
};

const startSendingFrames = () => {
  if (frameInterval) return; // 防止多次启动定时器
  frameInterval = setInterval(captureFrame, 200); // 每200毫秒捕获并发送一次
};

const startCamera = async () => {
  const stream = await navigator.mediaDevices.getUserMedia({
    video: true // 请求视频流
  });
  if (videoElement.value) {
    videoElement.value.srcObject = stream;
    cameraActive.value = true;
    startSendingFrames(); // 开始发送视频帧
  }
};

// 停止摄像头
const stopCamera = () => {
  if (videoElement.value && videoElement.value.srcObject) {
    const stream = videoElement.value.srcObject as MediaStream;
    const tracks = stream.getTracks();
    tracks.forEach(track => track.stop());
    cameraActive.value = false;
  }
  stopSendingFrames(); // 停止发送视频帧
  closeWebSocket();
};

// 切换摄像头状态
const toggleCamera = () => {
  if (cameraActive.value) {
    stopCamera();
  } else {
    setupWebSocket();
    startCamera();
  }
};

// 清理资源
onBeforeUnmount(() => {
  if (videoElement.value && videoElement.value.srcObject) {
    const stream = videoElement.value.srcObject as MediaStream;
    const tracks = stream.getTracks();
    tracks.forEach(track => track.stop());
  }
  stopSendingFrames(); // 停止发送视频帧
  closeWebSocket(); // 关闭WebSocket连接
});
</script>

<template>
  <div class="camera-container">
    <video ref="videoElement" class="video" autoplay playsinline muted :style="{ filter: videoFilter }"></video>
    <div v-if="error" class="error-message">{{ error }}</div>
  </div>
  <div style="margin-top: 50px">
    <AButton type="primary" size="large" shape="round" :loading="authStore.loginLoading" @click="toggleCamera">
      {{ cameraActive ? '关闭摄像头' : '打开摄像头' }}
    </AButton>
  </div>
</template>

<style scoped>
.camera-container {
  position: relative;
  margin-top: 20px;
  width: 100%;
  height: 100%;
}

.video {
  width: 300px;
  height: 300px;
  display: block;
  margin: 0 auto; /* 将视频居中 */
  object-fit: cover;
  border-radius: 150px;
  border:
    2px solid,
    #646cff; /* 设置视频边框 */
  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
}

.error-message {
  color: red;
  text-align: center;
  margin-top: 10px;
}

button {
  position: absolute;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  padding: 10px 20px;
  background-color: #007bff;
  color: white;
  border: none;
  border-radius: 5px;
  cursor: pointer;
}

button:hover {
  background-color: #0056b3;
}
</style>
